/*
 * @Date         : 2022-06-29 10:44:50
 * @LastEditors  : zu1662
 * @LastEditTime : 2024-05-24 14:32:44
 * @Description  : 文章 controller
 *
 * Copyright © 2022 by zu1662, All Rights Reserved.
 */

import {
  Controller,
  HttpCode,
  HttpStatus,
  Post,
  Query,
  Param,
  Delete,
  Body,
  Get,
  Patch,
} from '@nestjs/common';
import { ApiResponse, ApiTags } from '@nestjs/swagger';
import { PaginationService } from 'src/utils/pagination/service/pagination.service';
import { Response } from 'src/utils/response/response.decorator';
import { AuthJwtGuard, User } from 'src/auth/auth.decorator';

import { UserEntity } from '../user/user.entity';
import { UserService } from '../user/user.service';
import { ArticleEntity } from './article.entity';
import { ArticleService } from './article.service';
import { ArticleListDto } from './dto/article.list.dto';
import { ArticleDetailSerialization } from './serialization/article.detail.serialization';
import { DebuggerService } from 'src/debugger/service/debugger.service';

@ApiTags('Article')
@Controller('article')
export class ArticleController {
  constructor(
    private readonly articleService: ArticleService,
    private readonly paginationService: PaginationService,
    private readonly userService: UserService,
    private readonly debuggerService: DebuggerService
  ) {}

  /**
   * 创建文章
   * @param article
   */
  @ApiResponse({ status: 200, description: '创建文章', type: [ArticleEntity] })
  @Response('article.create')
  @Post()
  @AuthJwtGuard()
  create(@Body() article) {
    return this.articleService.create(article);
  }

  /**
   * 获取所有文章
   */
  // @AuthJwtGuard()
  @Get()
  @HttpCode(HttpStatus.OK)
  async findAll(@Query() queryParams: ArticleListDto) {
    const { page, perPage, search, sort, availableSearch, availableSort, status, ...otherParams } =
      queryParams;
    const skip: number = await this.paginationService.skip(page, perPage);
    this.debuggerService.info('artice list', 'ArticleController', 'list', 'ok');
    // 获取分页，排序数据
    const result = await this.articleService.findAll({
      skip,
      page,
      perPage,
      sort,
      status,
      search,
      availableSearch,
      filters: otherParams,
    });
    // 总条数
    const totalData = result.totalData;
    // 根据总条数分页
    const totalPage: number = await this.paginationService.totalPage(totalData, perPage);
    const articleData: ArticleDetailSerialization[] = await this.articleService.serializationList(
      result.data
    );
    return {
      totalData,
      totalPage,
      currentPage: page,
      perPage,
      availableSearch,
      availableSort,
      data: articleData,
    };
  }

  /**
   * 获取分类下所有文章
   */
  @Response('article.categoryArticles')
  @HttpCode(HttpStatus.OK)
  @Get('/category/:id')
  findArticlesByCategory(@Param('id') category, @Query() queryParams) {
    return this.articleService.findArticlesByCategory(category, queryParams);
  }

  /**
   * 获取标签下所有文章
   */
  @Response('article.tagArticles')
  @HttpCode(HttpStatus.OK)
  @Get('/tag/:id')
  findArticlesByTag(@Param('id') tag, @Query() queryParams) {
    return this.articleService.findArticlesByTag(tag, queryParams);
  }

  /**
   * 获取所有推荐文章
   */
  @Response('article.allRecommend')
  @HttpCode(HttpStatus.OK)
  @Get('/all/recommend')
  getRecommendArticles() {
    return this.articleService.getRecommendArticles();
  }

  /**
   * 获取所有文章归档
   */
  @Response('article.archives')
  @HttpCode(HttpStatus.OK)
  @Get('/archives')
  getArchives(): Promise<{ [key: string]: ArticleEntity[] }> {
    return this.articleService.getArchives();
  }

  /**
   * 获取相应文章的推荐文章
   */
  @Response('article.recommend')
  @HttpCode(HttpStatus.OK)
  @Get('/recommend')
  recommend(@Query('articleId') articleId) {
    return this.articleService.recommend(articleId);
  }

  /**
   * 获取指定文章
   * @param id
   */
  @Response('article.detail')
  @HttpCode(HttpStatus.OK)
  @Get(':id')
  async findById(@User() tokenUser: UserEntity, @Param('id') id, @Query('status') status) {
    try {
      const userId = tokenUser.id;
      const exist = await this.userService.findById(userId);
      const isAdmin = userId && exist.role === 'admin';
      return this.articleService.findById(id, status, isAdmin);
    } catch (e) {
      return this.articleService.findById(id, status);
    }
  }

  /**
   * 校验文章密码
   * @param id
   * @param article
   */
  @Response('article.checkPassword')
  @HttpCode(HttpStatus.OK)
  @Post(':id/checkPassword')
  checkPassword(@Param('id') id, @Body() article: ArticleEntity) {
    return this.articleService.checkPassword(id, article);
  }

  /**
   * 文章访问量 +1
   */
  @Response('article.views')
  @HttpCode(HttpStatus.OK)
  @Post(':id/views')
  updateViewsById(@Param('id') id) {
    return this.articleService.updateViewsById(id);
  }

  /**
   * 文章收藏量 +1
   */
  @Response('article.likes')
  @HttpCode(HttpStatus.OK)
  @Post(':id/likes')
  updateLikesById(@Param('id') id, @Body('type') type) {
    return this.articleService.updateLikesById(id, type);
  }

  /**
   * 更新文章
   * @param id
   * @param article
   */
  @Response('article.update')
  // @AuthJwtGuard()
  @HttpCode(HttpStatus.OK)
  @Patch(':id')
  async updateById(@Param('id') id, @Body() article: ArticleEntity) {
    return this.articleService.updateById(id, article);
  }

  /**
   * 删除文章
   * @param id
   */
  @Response('article.delete')
  // @AuthJwtGuard()
  @Delete(':id')
  deleteById(@Param('id') id) {
    return this.articleService.deleteById(id);
  }
}
